package com.hotec.PROJECT_NAME.component.exception.handler;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.hotec.PROJECT_NAME.component.basic.JsonContent;
import com.hotec.PROJECT_NAME.component.exception.exc.BizException;
import com.hotec.PROJECT_NAME.component.exception.exc.ErrorException;
import com.hotec.PROJECT_NAME.modules.sys.entity.SysUrlLog;
import com.hotec.PROJECT_NAME.modules.sys.service.SysUrlLogService;
import com.hotec.PROJECT_NAME.utils.UtilsLog;
import com.hotec.PROJECT_NAME.utils.UtilsSpring;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;

/**
 * @author
 */
@RestControllerAdvice
public class ExceptionHandlerController {
    @ExceptionHandler
    public JsonContent handler(Exception exception) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();

        if(ObjectUtil.isNull(attributes)) return JsonContent.error(500, new Exception("系统异常，请联系管理员"));

        HttpServletResponse response = attributes.getResponse();

        if(ObjectUtil.isNull(response)) return JsonContent.error(500, new Exception("系统异常，请联系管理员"));

        UtilsLog.log(this.getClass(), exception);
        if (exception instanceof BizException) {
            return JsonContent.error(((BizException) exception).getCode(), exception);
        }
        if (exception instanceof PersistenceException) {
            return JsonContent.error("数据库操作失败，请联系管理员");
        }
        if (exception instanceof ErrorException) {
            response.setStatus(500);

            return JsonContent.error(exception.getMessage());
        }
        if (exception instanceof MethodArgumentNotValidException) {
            if (((MethodArgumentNotValidException) exception).getBindingResult().getFieldErrors().size() > 0) {
                String field = ((MethodArgumentNotValidException) exception).getBindingResult().getFieldErrors().get(0).getField();
                String defaultMessage = ((MethodArgumentNotValidException) exception).getBindingResult().getFieldErrors().get(0).getDefaultMessage();
                return JsonContent.error(500, new BizException(500, field + defaultMessage));
            }
            return JsonContent.error(500, exception);
        }
        if (exception.getCause() instanceof JsonMappingException) {
            return JsonContent.error("参数错误,请检查输入的参数");
        } else if (exception instanceof MultipartException) {
            response.setStatus(500);
            if ((((MultipartException) exception).getRootCause()) instanceof FileUploadBase.FileSizeLimitExceededException) {
                return JsonContent.error("上传失败:请上传小于300M的文件");
            } else {
                return JsonContent.error("上传失败,请联系管理员");
            }
        }else if (exception instanceof DuplicateKeyException) {
            String dataMsg = ReUtil.get("(?<=').*?(?=')", exception.getMessage(), 0);

            return JsonContent.error("【" + dataMsg + "】" + "数据已被占用");
        }

        String errorMsg = StrUtil.blankToDefault(exception.getMessage(), "系统异常，请联系管理员");

        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();

        String s = request.getRequestURL().toString();
        try {
            BufferedReader br = null;
            br = request.getReader();
            String str;
            StringBuilder wholeStr = new StringBuilder();
            while ((str = br.readLine()) != null) {
                wholeStr.append(str);
            }
            SysUrlLogService sysUrlLogService = UtilsSpring.getBean(SysUrlLogService.class);
            SysUrlLog sysUrlLog = new SysUrlLog();
            sysUrlLog.setContent(s);
            sysUrlLog.setRemark(wholeStr.toString());
            StackTraceElement[] stackTrace = exception.getStackTrace();
            for (StackTraceElement stackTraceElement : stackTrace) {
                if(stackTraceElement.toString().contains("hotec")){
                    sysUrlLog.setExceptions(exception.toString()+"\t"+ stackTraceElement.toString());
                    break;
                }
            }
            sysUrlLogService.save(sysUrlLog);
        }catch (Exception e){
//            System.out.println(e);
        }
        return JsonContent.error(errorMsg);
    }
}
